package cn.careerx.app.common.models;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.SqlRow;

import redis.clients.jedis.Jedis;

public class Skill  implements Serializable{

	private static final long serialVersionUID = -309619307800662562L;
	
	private String id;
	private String skillName;
	private String skillShortName;
	private String skillColor;
	private String skillComment;
	private String levelJson;
	private Integer levelCount;
	
	//Redis keys
	private static final String SKILLINFO_KEY = "skillInfo:";
	private static final String OCC_SKILLSET_KEY = "occupation.skillSite:";
	private static final String SKILLSET_SKILL_KEY = "skillsite.skill:";
	private static final String SKILL_REQUIRE_KEY = "skillreqInfo:";
	private static final String SKILLSET_INFO = "skillsetInfo:";
	private static final String OCC_SKILL_KEY = "occupation.skills:";
	
	public static Skill create(){
		return new Skill();
	}
	
	public static Map<String,Object> getSkillSetAndSkillsByOcc(Database db,Jedis jedis,String occId,String occLevel) throws Exception{
		List<String> skillSets = getSkillSetByOccId(db, jedis, occId);
		List<Map<String,Object>> skillSetList = new ArrayList<Map<String,Object>>();
		for(String skillSetId : skillSets){
			Map<String,Object> mapTemp = new HashMap<String,Object>();
			//获取方向详情
			Map<String,String> skillSet = getSkillSetById(db, jedis, skillSetId);
			mapTemp.put("ssId",skillSet.get("id"));
			mapTemp.put("ssName", skillSet.get("name"));
			//获取方向对应的skillSeq列表
			List<String> skillReqIds = getSkillReqsBySkillSet(db, jedis, skillSetId,occLevel);
			//方向等级对应的技能map
			Map<String,List<Map<String,String>>> ssLevelMap = new TreeMap<String,List<Map<String,String>>>();
			for(String skillResId : skillReqIds){
				//获取技能需求详情
				Map<String,String> skillReq = getSkillReqsById(db, jedis, skillResId);
				String ssLevelTemp = skillReq.get("ssLevel");
				String sIdTemp = skillReq.get("sId");
				String sLevelTemp = skillReq.get("sTargetLevel");
				//技能根据方向等级分组列表
				List<Map<String,String>> sList;
				if(ssLevelMap.containsKey(ssLevelTemp)){
					sList = ssLevelMap.get(ssLevelTemp);
				}else{
					sList = new ArrayList<Map<String,String>>();
					ssLevelMap.put(ssLevelTemp, sList);
				}
				Map<String,String> sMapTemp = new HashMap<String,String>();
				sMapTemp.put("sId", sIdTemp);
				sMapTemp.put("sTargetLevel", sLevelTemp);
				sList.add(sMapTemp);
			}
			//将Map转为List
			List<Map<String,Object>> ll = new ArrayList<Map<String,Object>>();
			for(Entry<String,List<Map<String,String>>> entry : ssLevelMap.entrySet()){
				Map<String,Object> temp = new HashMap<String,Object>();
				temp.put("ssLevel", entry.getKey());
				temp.put("skills", entry.getValue());
				ll.add(temp);
			}
			mapTemp.put("ssLevelData", ll);
			skillSetList.add(mapTemp);
		}
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("occLevel", occLevel);
		result.put("skillSets", skillSetList);
		return result;
	}
	
	public static List<Skill> getAllSkillsByOccId(Database db,Jedis jedis,String occId){
		String key = OCC_SKILL_KEY + occId;
		List<Skill> result = new ArrayList<Skill>();
		List<String> slist;
		if(jedis.exists(key)){
			slist = jedis.lrange(key, 0, -1);
		}else{
			EbeanServer es = db.getDbByPartitionKey("CAREERX", "");
			List<SqlRow> rows = es.createSqlQuery("SELECT ID FROM CX_SKILLSET_SKILL WHERE SS_ID IN (SELECT ID FROM CX_SKILLSET WHERE OCC_ID=?)").setParameter(1, occId).findList();
			slist = new ArrayList<String>();
			for(SqlRow row : rows){
				String sId = row.getString("ID");
				slist.add(sId);
			}
			String[] sarr = new String[slist.size()];
			sarr = slist.toArray(sarr);
			if(sarr.length>0){
				jedis.lpush(key, sarr);
			}
		}
		for(String sId : slist){
			Skill skill = getSkillById(db, jedis, sId);
			if(skill!=null)
				result.add(skill);
		}
		return result;
	}
	
	public static Skill getSkillById(Database db,Jedis jedis,String id){
		String key = SKILLINFO_KEY+id;
		String keyId="id",keySkillName="name",keyShortName="sName",keySkillColor = "color",keySkillComment="comment",keyLevelCount="levelCount",keyLevelJson="levelJson";
		Map<String,String> kmap = null;
		if(jedis.exists(key)){
			kmap = jedis.hgetAll(key);
			
		}else{
			EbeanServer es  = db.getDbByPartitionKey("CAREERX", "");
			SqlRow row = es.createSqlQuery("SELECT * FROM CX_SKILL WHERE ID=?")
									.setParameter(1, id).findUnique();
			if(row==null){
				return null;
			}
			kmap = new HashMap<String,String>();
			kmap.put(keyId, row.getString("ID"));
			kmap.put(keySkillName, dealNull(row.getString("NAME")));
			kmap.put(keySkillColor, dealNull(row.getString("COLOR")));
			kmap.put(keyShortName, dealNull(row.getString("SNAME")));
			kmap.put(keySkillComment, dealNull(row.getString("COMMENT")));
			kmap.put(keyLevelCount, dealNull(row.getInteger("LEVEL_COUNT")));
			kmap.put(keyLevelJson, dealNull(row.getString("LEVEL_JSON")));
			jedis.hmset(key, kmap);
		}
		Skill skill = Skill.create()
						   .setId(kmap.get(keyId))
						   .setSkillName(kmap.get(keySkillName)) 
						   .setSkillColor(kmap.get(keySkillColor))
						   .setSkillShortName(kmap.get(keyShortName))
						   .setSkillComment(kmap.get(keySkillComment))
						   .setLevelCount(Integer.parseInt(kmap.get(keyLevelCount)))
						   .setLevelJson(kmap.get(keyLevelJson));
		return skill;
	}
	
	
	public static List<String> getSkillSetByOccId(Database db,Jedis jedis,String occId){
		String key = OCC_SKILLSET_KEY+occId;
		if(jedis.exists(key)){
			List<String> result = jedis.lrange(key, 0, -1);
			return result;
		}
		EbeanServer es = db.getDbByPartitionKey("CAREERX", "");
		List<SqlRow> list = es.createSqlQuery("SELECT ID FROM CX_SKILLSET WHERE OCC_ID=?").setParameter(1, occId).findList();
		List<String> result = new ArrayList<String>();
		for(SqlRow row : list){
			String ssId = row.getString("ID");
			jedis.lpush(key, ssId);
			result.add(ssId);
		}
		return result;
	}
	
	public static Map<String,String> getSkillSetById(Database db,Jedis jedis,String ssId){
		String key = SKILLSET_INFO+ssId;
		if(jedis.exists(key)){
			return jedis.hgetAll(key);
		}
		EbeanServer es = db.getDbByPartitionKey("CAREERX", "");
		SqlRow row = es.createSqlQuery("SELECT * FROM CX_SKILLSET WHERE ID=?").setParameter(1, ssId).findUnique();
		Map<String,String> map = new HashMap<String,String>();
		map.put("id", row.getString("ID"));
		map.put("name", row.getString("NAME"));
		map.put("occId",row.getString("OCC_ID"));
		jedis.hmset(key, map);
		return map;
	}
	
	public static List<String> getSkillReqsBySkillSet(Database db,Jedis jedis,String ssId,String level){
		String key = SKILLSET_SKILL_KEY+ssId;
		if(jedis.exists(key)){
			List<String> result = jedis.lrange(key, 0, -1);
			return result;
		}
		EbeanServer es = db.getDbByPartitionKey("CAREERX", "");
		List<SqlRow> list = es.createSqlQuery("SELECT ID FROM CX_SKILLSET_SKILL WHERE SS_ID=? and OCC_LEVEL=? ").setParameter(1, ssId).setParameter(2, level).findList();
		List<String> result = new ArrayList<String>();
		for(SqlRow row : list){
			String rId = row.getString("ID");
			jedis.lpush(key, rId);
			result.add(rId);
		}
		return result;
	}
	
	public static Map<String,String> getSkillReqsById(Database db,Jedis jedis,String id){
		String key = SKILL_REQUIRE_KEY+id;
		if(jedis.exists(key)){
			return jedis.hgetAll(key);
		}
		EbeanServer es = db.getDbByPartitionKey("CAREERX", "");
		SqlRow row = es.createSqlQuery("SELECT * FROM CX_SKILLSET_SKILL WHERE ID=?").setParameter(1, id).findUnique();
		Map<String,String> result = new HashMap<String,String>();
		result.put("ssId", row.getString("SS_ID"));
		result.put("sId", row.getString("S_ID"));
		result.put("ssLevel", String.valueOf(row.getInteger("SS_LEVEL")));
		result.put("occLevel", String.valueOf(row.getInteger("OCC_LEVEL")));
		result.put("sTargetLevel", String.valueOf(row.getInteger("S_TARGET_LEVEL")));
		jedis.hmset(key, result);
		return result;
	}
	
	private static String dealNull(String str){
		return str==null?"":str;
	}
	
	private static String dealNull(Integer instr){
		return instr==null?"0":String.valueOf(instr);
	}
	
	/*****************************Setter and Getters******************************************/
	public String getId() {
		return id == null ? "" : id;
	}

	public Skill setId(String id) {
		this.id = id;
		return this;
	}

	public String getSkillName() {
		return skillName == null ? "" : skillName;
	}

	public Skill setSkillName(String skillName) {
		this.skillName = skillName;
		return this;
	}

	public String getSkillShortName() {
		return skillShortName == null ? "" : skillShortName;
	}

	public Skill setSkillShortName(String skillShortName) {
		this.skillShortName = skillShortName;
		return this;
	}

	public String getSkillColor() {
		return skillColor == null ? "" : skillColor;
	}

	public Skill setSkillColor(String skillColor) {
		this.skillColor = skillColor;
		return this;
	}

	public String getSkillComment() {
		return skillComment == null ? "" : skillComment;
	}

	public Skill setSkillComment(String skillComment) {
		this.skillComment = skillComment;
		return this;
	}

	public String getLevelJson() {
		return levelJson == null ? "" : levelJson;
	}

	public Skill setLevelJson(String levelJson) {
		this.levelJson = levelJson;
		return this;
	}

	public Integer getLevelCount() {
		return levelCount == null ? 0 : levelCount;
	}

	public Skill setLevelCount(Integer levelCount) {
		this.levelCount = levelCount;
		return this;
	}

}
